import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
// import ReportFormOrderStatistics from '@main/entities/service/admin/reportForm/report-form-period-status-monitoring.entity';
import { In, Repository, Between, Like } from 'typeorm';
// import BaseMachine from '@main/entities/service/admin/base/base-machine.entity';
import WipOrderReport from '@main/entities/service/admin/wip/wip-order-report.entity';
import ProductionOrder from '@main/entities/service/admin/production/production-order.entity';
import { ApiException } from '@main/common/exceptions/api.exception';
import { generateExcelFn } from '@main/excel';
import { format } from 'date-fns';

@Injectable()
export class ReportFormOrderStatisticsService {
  constructor(
    // @InjectRepository(BaseMachine)
    // private machineRepository: Repository<BaseMachine>,
    // @InjectRepository(ReportFormOrderStatistics)
    // private reportFormOrderStatisticsRepository: Repository<ReportFormOrderStatistics>,
    @InjectRepository(WipOrderReport)
    private orderReportRepository: Repository<WipOrderReport>,
    @InjectRepository(ProductionOrder)
    private orderRepository: Repository<ProductionOrder>
  ) {}

  /**
   * 罗列所有配置
   */
  async page(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { orderCreateDate, fastSearch, ids = [] } = entity;

    const where: any[] = []; // 初始化为数组以便后续拼接

    // 处理 userIdList 进行匹配
    if (orderCreateDate && orderCreateDate.length) {
      if (fastSearch) {
        where.push(
          {
            materialCode: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          },
          {
            materialName: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          },
          {
            orderCode: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          },
          {
            customCode: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          },
          {
            customShort: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          },
          {
            customName: Like(`%${fastSearch}%`),
            createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
          }
        );
      } else {
        where.push({
          createTime: Between(new Date(orderCreateDate[0]), new Date(orderCreateDate[1])),
        });
      }
    }

    if (ids && ids.length) {
      for (const item of where) {
        item['id'] = In(ids);
      }
    }

    const [orderList, total]: any = await this.orderRepository.findAndCount({
      where,
      order: {
        updateTime: 'DESC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });

    await Promise.all(
      orderList.map(async (item) => {
        const {
          orderCode,
          machineCode,
          actualCompleteDate: aDate,
          orderStatusCode,
          customerDeliveryDate,
          materialLength,
          materialWidth,
          materialHeight,
        } = item;

        const orderReportList = await this.orderReportRepository.find({
          where: {
            orderCode,
            machineCode,
            reportFinishStatus: 1,
          },
          order: { updateTime: 'DESC' },
        });

        let allReportNum = 0;

        let allGoodNum = 0;

        let allBadNum = 0;

        let orderCreateDate = format(new Date(item.createTime), 'yyyy-MM-dd'); // 工单创建日期

        let actualcreationDate = ''; // 实际开工日期

        let actualcreationDateTime: any = '';

        let actualCompleteDate: any = ''; // 实际完工日期

        let actualCompleteTime: any = ''; // 实际完工日期

        let orderDuration: any = ''; // 工单时长（天）

        let delayDays: any = ''; // 延迟天数

        if (orderReportList && orderReportList.length) {
          for (const mItem of orderReportList) {
            const { reportStatus, reportConfirmNum, reportNum, badNum, goodNum } = mItem;

            if (reportStatus === 1) {
              allReportNum += reportConfirmNum;
            } else {
              allReportNum += reportNum;
            }

            allGoodNum += goodNum;

            allBadNum += badNum;
          }

          const lastObj = orderReportList[orderReportList.length - 1];

          actualcreationDate = format(new Date(lastObj.createTime), 'yyyy-MM-dd'); // 实际开工日期

          actualcreationDateTime = new Date(lastObj.createTime).getTime();
        }

        if (orderStatusCode === '40') {
          if (aDate) {
            actualCompleteDate = format(new Date(aDate), 'yyyy-MM-dd'); // 实际完工日期

            actualCompleteTime = aDate;
          }
        } else if (orderStatusCode === '20' || orderStatusCode === '30') {
          actualCompleteTime = new Date().getTime();
        }

        if (actualcreationDateTime && actualCompleteTime) {
          orderDuration = (
            (actualCompleteTime - actualcreationDateTime) /
            (1000 * 60 * 60 * 24)
          ).toFixed(2); // 工单时长（天）
        }

        if (customerDeliveryDate) {
          delayDays = (
            (actualCompleteTime - new Date(customerDeliveryDate).getTime()) /
            (1000 * 60 * 60 * 24)
          ).toFixed(2); // 延迟天数

          if (Number(delayDays) < 0) {
            delayDays = '';
          }

          item.customerDeliveryDate = format(new Date(customerDeliveryDate), 'yyyy-MM-dd');
        }

        item.materialStandards = `${materialLength}*${materialWidth}*${materialHeight}`;

        item.goodNum = allGoodNum;

        item.badNum = allBadNum;

        item.completeNum = allReportNum;

        item.actualCreationDate = actualcreationDate;

        item.actualCompleteDate = actualCompleteDate;

        item.orderDuration = orderDuration;

        item.delayDays = delayDays;

        item.orderCreateDate = orderCreateDate;
      })
    );

    return [orderList, total];
  }

  async export(dto, lang) {
    const [list] = await this.page(dto);

    if (!list || !(list as any).length) {
      throw new ApiException(10052);
    }

    const dataList = list;

    return await generateExcelFn(
      {
        sheetName: 'orderStatistics',
        mainHeaderList: [
          {
            label: 'orderCode',
          },
          {
            label: 'orderStatus',
            prop: 'orderStatusName',
          },
          {
            label: 'orderType',
          },
          {
            label: 'paperboardNum',
          },
          {
            label: 'orderNum',
          },
          {
            label: 'completeNum',
          },
          {
            label: 'goodNum',
          },
          {
            label: 'badNum',
          },
          {
            label: 'customName',
          },
          {
            label: 'materialCode',
          },
          {
            label: 'materialName',
          },
          {
            label: 'materialStandards',
          },
          {
            label: 'customerDeliveryDate',
          },
          {
            label: 'orderCreateDate',
          },
          {
            label: 'actualCreationDate',
          },
          {
            label: 'actualCompleteTime',
            prop: 'actualCompleteDate',
          },
          {
            label: 'orderDuration',
          },
          {
            label: 'delayDays',
          },
        ],
        dataList,
      },
      lang
    );
  }
}
